<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <link rel="stylesheet" href="../static/lib/bootstrap/css/bootstrap.css">
    <title>Title</title>
    <style>
    </style>
</head>
<body ng-app="test" ng-controller="c1">
<div>
    <label class="btn btn-default" for="upload-files">点击上传文件</label>
    <input type="file" class="hidden upload-files" id="upload-files" file-select file-uploader="fileUploader" multiple>
    <table class="table">
        <thead>
        <tr>
            <td>序号</td>
            <td>文件名</td>
            <td>进度</td>
            <td></td>
        </tr>
        </thead>
        <tbody>
        <tr ng-repeat="item in fileUploader.files track by $index">
            <td>{{$index}}</td>
            <td>{{item.name}}</td>
            <td>
                <div class="progress">
                    <div class="progress-bar" role="progressbar" aria-valuenow="{{item.progress}}"
                         ng-style="{width:item.progress + '%'}" aria-valuemin="0" aria-valuemax="100"></div>
                </div>
            </td>
            <td>
                <button class="btn" ng-click="fileUploader.remove(item)"
                        ng-class="{'btn-warning':!item.isDone,'disabled':!item.isDone,'btn-success':item.isDone && item.isSuccess,'btn-danger':item.isDone && item.isFailure}">
                    移除
                </button>
            </td>
        </tr>
        </tbody>
    </table>
</div>

<p>{{files.length}}</p>
<button ng-click="show()">show</button>
<script src="../static/js/config.js"></script>
<script src="../static/lib/angular/angular.js"></script>
<script>


    angular
        .module("makerspace.component", [])
        .factory("FileItem", function () {

            /**
             * FileUploader中的文件项目
             * @param name 文件名
             * @param finished 是否已经上传,该参数会改变文件的初始状态
             */
            function FileItem(name,finished) {
                this.name = name || "";
                this.isDone = !!finished; //是否经过上传
                this.isSuccess = !!finished; // 上传是否成功
                this.isFailure = false; // 上传是否失败
                this.progress = !finished ? 0 : 100; // 上传进度

            }

            return FileItem;
        })
        .factory("FileUploader", ['$http', 'FileItem', function ($http, FileItem) {

            /**
             * FileUploader主类
             *
             * @param config
             *          {
                 *           uploadUrl:{string},上传文件接口的url,只支持单个文件上传,默认为'upload-file'
                 *           deleteUrl:{string},删除文件接口的url,只支持删除单个文件,默认为‘delete-file'
                 *           filter:{array},接收的文件类型,需要加.号,默认为[],全部接收.
                 *                          使用方法例如['.zip','.jpg','.jpeg']
                 *           maxSize:{number},上传的最大尺寸(单位B),默认为1024*1024
                 *           maxFileNumber:{number},上传的最大文件数量,默认为5
                 *         }
             * @constructor
             */
            function FileUploader(config) {
                this.config = {
                    uploadUrl: config.uploadUrl || 'upload-file',
                    deleteUrl: config.deleteUrl || 'delete-file',
                    filter: config.filter || [],
                    maxSize: config.maxSize || 1024 * 1024,
                    maxFileNumber: config.maxFileNumber || 5
                };

                this.files = [];
            }

            // 检查文件类型是否符合要求,不符合要求返回true
            FileUploader.prototype._isTypeIllegal = function (type) {
                if (this.config.filter.length === 0) {
                    return false;
                }

                return this.config.filter.lastIndexOf(type) === -1;
            };

            // 检查文件是否重复,如果重复返回true
            FileUploader.prototype._isFileDuplicate = function (name) {
                for (var i = 0; i < this.files.length; i++) {
                    console.log(this.files);
                    console.log(name);
                    if (this.files[i].name === name) {
                        return true;
                    }
                }

                return false;

            };

            /**
             * 检查文件数量是否符合要求,不符合要求返回true
             */
            FileUploader.prototype._isFileNumberOverflow = function (number) {
                return this.files.length + number > this.config.maxFileNumber;
            };

            /**
             * 检查文件尺寸是否符合要求，不符合返回true
             */
            FileUploader.prototype._isSizeOverflow = function (size) {
                return this.config.maxSize < size;
            };


            /**
             * 检查全部要求的项目,有一项不符合则提示,并返回true
             * @param files html5 FileList对象
             */
            FileUploader.prototype.check = function (files) {
                for (var i = 0; i < files.length; i++) {
                    var file = files[i];
                    if (this._isTypeIllegal(file.name.slice(file.name.lastIndexOf(".")))) {
                        alert("上传的文件类型不符合要求!");
                        return true;
                    }

                    if (this._isSizeOverflow(file.size)) {
                        alert("上传的文件尺寸超出范围!");
                        return true;
                    }

                    if (this._isFileNumberOverflow(files.length)) {
                        alert("上传的文件数超出限制!");
                        return true;
                    }

                    if (this._isFileDuplicate(file.name)) {
                        alert("要上传相同的文件，请先移除已上传的文件");
                        return true;
                    }
                }

                return false;
            };

            /**
             * 添加文件
             * @param file html5 File对象
             */
            FileUploader.prototype.addFile = function (file) {
                var fileItem = new FileItem(file.name);

                this.files.push(fileItem);

                var obj = this;
                var formData = new FormData();
                formData.append("file", file);

                $http({
                    url: obj.config.uploadUrl,
                    method: 'POST',
                    data: formData,
                    headers: {
                        'Content-Type': false
                    },
                    // 进度处理器
                    uploadEventHandlers: {
                        progress: function (e) {
                            if (e.lengthComputable) {
                                fileItem.progress = (e.loaded / e.total) * 100;
                                console.log("uploading file: ", file.name, ",progress: ", fileItem.progress);
                            }
                        }
                    }
                }).then(
                    function success(resp) {
                        fileItem.isDone = true;
                        fileItem.isSuccess = true;
                        fileItem.isFailure = false;
                    },
                    function error(resp) {
                        fileItem.isDone = true;
                        fileItem.isSuccess = false;
                        fileItem.isFailure = true;
                    }
                );

            };

            FileUploader.prototype.remove = function (fileItem) {

                var obj = this;

                // 如果上传完成(无论成功与否),向后台请求文件删除
                if (fileItem.isDone) {
                    $http({
                        url: obj.config.deleteUrl,
                        method: 'POST',
                        data: angular.toJson({
                            fileName: fileItem.name
                        })
                    }).then(
                        function success(resp) {
                            obj.files.splice(obj.files.lastIndexOf(fileItem), 1);
                            console.log("file ", fileItem.name, " is deleted.");
                        },
                        function error() {
                            console.log("file ", fileItem.name, " not deleted.");
                        });
                }
            };

            return FileUploader;
        }])
        .directive("fileSelect", function () {
            return {
                restrict: "A",
                scope: {
                    fileUploader: "="
                },
                link: function (scope, element, attrs) {

                    element.bind("change", function (e) {
                        var newFiles = e.target.files;
                        var isError = false;

                        if (scope.fileUploader.check(newFiles)) {
                            isError = true;
                        }

                        if (!isError) {
                            for (var i = 0; i < newFiles.length; i++) {
                                console.log(newFiles[i]);
                                scope.fileUploader.addFile(newFiles[i]);
                            }
                        }

                        scope.$apply();
                    });

                }

            }
        });

    angular.module("test", [
        'makerspace.component'
    ]).controller("c1", ["$scope", "FileUploader", "FileItem", function ($scope, FileUploader, FileItem) {
        $scope.fileUploader = new FileUploader({
            uploadUrl: requestRootUrl + "api/register/upload-file",
            deleteUrl: requestRootUrl + "api/register/delete-file",
            maxSize: 50 * 1024 * 1024
        });

        console.log(FileItem);

        $scope.fileUploader.files = [
            new FileItem("application.zip",true),
            new FileItem("list.jpg",true)
        ];

        $scope.show = function () {
            console.log($scope.fileUploader);
        };
    }]);
</script>
</body>
</html>